﻿using System;
using System.Collections.Generic;
using System.Linq;
using Sigil.Impl;

namespace Sigil
{
	/// <summary>
	/// Represents an IL operation, and the subsequent operations that may use it's result.
	/// </summary>
	public sealed class OperationResultUsage<DelegateType>
	{
		/// <summary>
		/// The operation that is producing a result.
		/// </summary>
		public Operation<DelegateType> ProducesResult { get; private set; }

		/// <summary>
		/// The operations that may use the result produced by the ProducesResult operation.
		/// </summary>
		public IEnumerable<Operation<DelegateType>> ResultUsedBy { get; private set; }

		internal IEnumerable<TypeOnStack> TypesProduced { get; private set; }

		internal OperationResultUsage(Operation<DelegateType> producer, IEnumerable<Operation<DelegateType>> users, IEnumerable<TypeOnStack> typesProduced)
		{
			ProducesResult = producer;
			ResultUsedBy = users;
			TypesProduced = typesProduced;
		}

		/// <summary>
		/// Returns a String representation of this OperationResultUsage.
		/// </summary>
		public override String ToString()
		{
			var users = String.Join(", ", ResultUsedBy.Select(r => r.ToString()).OrderBy(_ => _).ToArray());

			if (users.Length == 0)
			{
				return "(" + ProducesResult + ") result is unused";
			}

			return "(" + ProducesResult + ") result is used by (" + users + ")";
		}
	}
}